package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.util.Auth;
import com.xuecheng.api.content.model.dto.CourseTeacherDTO;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.enums.common.CommonEnum;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.convert.CourseTeacherConvert;
import com.xuecheng.content.entity.CourseBase;
import com.xuecheng.content.entity.CourseTeacher;
import com.xuecheng.content.mapper.CourseTeacherMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CourseTeacherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 课程-教师关系表 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CourseTeacherServiceImpl extends ServiceImpl<CourseTeacherMapper, CourseTeacher> implements CourseTeacherService {

    @Autowired
    private CourseBaseService courseBaseService;

    /**
     * 1.判断关键数据
     * courseId  companyId
     * 2.判断课程信息
     * 判断课程是否存在
     * 判断是否是同一家机构
     * 判断课程是否删除
     * 3.根据 courseId companyId查询教师信息
     */
    public List<CourseTeacherDTO> queryTeacherList(Long courseId, Long companyId,Boolean isPublish) {
        //1.判断关键数据
        if (ObjectUtils.isEmpty(courseId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.判断课程信息
        CourseBase courseBase = courseBaseService.getById(courseId);
        verifyPo(companyId, courseBase,isPublish);
        //3.根据 courseId 查询教师信息
        LambdaQueryWrapper<CourseTeacher> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseTeacher::getCourseId, courseId);

        List<CourseTeacher> courseTeachers = this.list(queryWrapper);

        List<CourseTeacherDTO> courseTeacherDTOS = CourseTeacherConvert.INSTANCE.entitys2dtos(courseTeachers);
        return courseTeacherDTOS;
    }

    private void verifyPo(Long companyId, CourseBase courseBase,Boolean isPublish) {
        //判断课程是否存在
        if (ObjectUtils.isEmpty(courseBase)) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        if (!ObjectUtils.isEmpty(companyId)) {
            //判断是否是同一家机构
            if (!ObjectUtils.nullSafeEquals(companyId, courseBase.getCompanyId())) {
                ExceptionCast.cast(CommonErrorCode.E_100108);
            }
        }

        //判断课程是否删除
        if (CommonEnum.DELETE_FLAG.getCodeInt().equals(courseBase.getStatus())) {
            ExceptionCast.cast(ContentErrorCode.E_120019);
        }
        if (!isPublish) {
            //判断课程的审核状态
            if (CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(courseBase.getAuditStatus()) ||
                    CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode().equals(courseBase.getAuditStatus()) ||
                    CourseAuditEnum.AUDIT_PASTED_STATUS.getCode().equals(courseBase.getAuditStatus())) {
                ExceptionCast.cast(ContentErrorCode.E_120014);
            }
        }


    }

    /**
     * 1.判断关键数据合法性
     * 根据前端  courseId  position teacherName companyId
     * 2.判断课程信息
     * 判断课程是否存在
     * 判断是否是同一家机构
     * 判断课程是否已经删除
     * 3.根据 courseTeacherId查询教师信息
     * 判断添加还是修改
     * 4.查询最新数据 返回dto 给前端
     */
    @Transactional
    public CourseTeacherDTO createOrModifyTeacher(CourseTeacherDTO dto, Long companyId) {
        //1.判断关键数据合法性
        if (ObjectUtils.isEmpty(dto.getCourseId()) ||
                StringUtil.isBlank(dto.getPosition()) ||
                StringUtil.isBlank(dto.getTeacherName()) ||
                ObjectUtils.isEmpty(companyId)) {

            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.判断课程信息
        CourseBase courseBase = courseBaseService.getById(dto.getCourseId());
        verifyPo(companyId, courseBase,false);
        //3.根据 courseTeacherId查询教师信息
        CourseTeacher courseTeacher = this.getById(dto.getCourseTeacherId());
        //判断添加还是修改
        if (ObjectUtils.isEmpty(courseTeacher)) {
            //添加
            courseTeacher = CourseTeacherConvert.INSTANCE.dto2entity(dto);
            courseTeacher.setId(null);
            courseTeacher.setCreateDate(LocalDateTime.now());

            boolean save = this.save(courseTeacher);
            if (!save) {
                ExceptionCast.cast(ContentErrorCode.E_1200504);
            }
        } else {
            LambdaUpdateWrapper<CourseTeacher> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(CourseTeacher::getTeacherName, dto.getTeacherName());
            updateWrapper.set(CourseTeacher::getIntroduction, dto.getIntroduction());
            updateWrapper.set(CourseTeacher::getPhotograph, dto.getPhotograph());
            updateWrapper.set(CourseTeacher::getPosition, dto.getPosition());
            updateWrapper.eq(CourseTeacher::getId, dto.getCourseTeacherId());

            boolean update = this.update(updateWrapper);
            if (!update) {
                ExceptionCast.cast(ContentErrorCode.E_1200501);
            }
        }
        //4.查询最新数据 返回dto 给前端
        CourseTeacher po = this.getById(dto.getCourseTeacherId());
        //po-->dto
        CourseTeacherDTO resultDto = CourseTeacherConvert.INSTANCE.entity2dto(po);
        return resultDto;
    }

    @Value("${file.service.bucket}")
    private String bucket;

    @Value("${file.qiniu.accessKey}")
    private String accessKey;

    @Value("${file.qiniu.secretKey}")
    private String secretKey;

    /**
     * 1.判断关键数据合法性
     * courseBaseId  courseTeacherId  companyId
     * 2.判断课程信息
     * 判断课程是否存在
     * 判断是否是同一家机构
     * 判断课程是否已经删除
     * 3.删除教师信息
     */
    @Transactional
    public void removeTeacher(Long courseBaseId, Long courseTeacherId, Long companyId) {
        //1.判断关键数据合法性
        if (ObjectUtils.isEmpty(courseBaseId) ||
                ObjectUtils.isEmpty(courseTeacherId) || ObjectUtils.isEmpty(companyId)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.判断课程信息
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        verifyPo(companyId, courseBase,false);
        //根据courseTeacherId 获得教师信息
        CourseTeacher courseTeacher = this.getById(courseTeacherId);
        if (ObjectUtils.isEmpty(courseTeacher)) {
            ExceptionCast.cast(ContentErrorCode.E_1200503);
        }
        //获得教师照片地址
        String photograph = courseTeacher.getPhotograph();

        //3.删除教师信息
        boolean result = this.removeById(courseTeacherId);
        if (!result) {
            ExceptionCast.cast(ContentErrorCode.E_1200505);
        }

        if (StringUtil.isNotBlank(photograph)) {
            //构造一个带指定 Region 对象的配置类
            Configuration cfg = new Configuration(Zone.huanan());
            //要删除的文件名称
            String key = photograph.substring(photograph.lastIndexOf("/") + 1);

            Auth auth = Auth.create(accessKey, secretKey);

            BucketManager bucketManager = new BucketManager(auth, cfg);
            try {
                bucketManager.delete(bucket, key);
            } catch (QiniuException ex) {
                //如果遇到异常，说明删除失败
               ExceptionCast.cast(ContentErrorCode.E_1200506);
            }
        }
    }
}
